package com.lry;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@Slf4j
public class Start {
    public static void main(String[] args) throws IOException {
        String goodsKey = "goodsKey";
        String errorKey = "errorKey";

        //redis设置库存
        Redis redis = new Redis();
        int nodeNum = 10;
        int nodeSku = 100;
        int concurrent = 100;


        for(int i=1;i<=nodeNum;i++){
            redis.set(goodsKey+i,nodeSku);
        }
        redis.set(errorKey,0);
        //设置一个故障检测系统，检测节点故障，如果检测到一个节点故障，就把节点剩余库存放到errorKey里

        List<Node> nodes = new ArrayList<>();
        //每台机器分10个
        for(int i=1;i<=nodeNum;i++) {
            Node node = new Node(nodeSku, "node" + i, goodsKey + i, errorKey, redis);
            if (i == nodeNum) {
                node.error = true;
            }
            nodes.add(node);
        }

        //故障检测
        for(Node node:nodes) {
            CompletableFuture.runAsync(()->{

                Integer remain = redis.get(node.getKey());
                if(null==remain || remain<=0){
                    return;
                }

                while(!node.error){
                    remain = redis.get(node.getKey());
                    if(null==remain || remain<=0){
                        return;
                    }
                }

                Integer errorNum = redis.incr(errorKey,remain);
                log.info("{}节点添加{}后errorNum={}",node.getName(),remain,errorNum);
            });
        }

        //每个机器开100个线程去抢这10个库存
        for(Node node:nodes) {
            List<Thread> threads = new ArrayList<>();
            for(int j=0;j<concurrent;j++){
                Thread thread = new Thread(()->{
                    for(int i=0;i<10;i++){
                        node.secKill(UUID.randomUUID().toString());
                    }
                });
                threads.add(thread);
            }
            threads.stream().parallel().forEach(Thread::start);
        }


        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("errorKey="+redis.get(errorKey));

        System.in.read();
    }
}
